
/*
 *
 * Copyright (C) 2008 Mattias Blomqvist, patr-blo at dsv dot su dot se
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;

using FlowLib.Events;
using FlowLib.Connections;
using FlowLib.Containers;
using ClientExample.Containers;
using ClientExample.Client.Interface;

namespace ClientExample.Controls
{
    public partial class MessagePanel : System.Windows.Forms.UserControl
    {
        public event FmdcEventHandler ActionUpdate;
        protected OnlineStatus info = null;
        protected Notification.NotificationActions notify = Notification.NotificationActions.None;

        public MessagePanel()
        {
			IntPtr h = Handle;  // This is for stupid mono stuff. Some how handle isnt created correctly if we dont do this :(
            ActionUpdate = new FmdcEventHandler(MessagePanel_ActionUpdate);
            InitializeComponent();

            richOutput.DetectUrls = Program.Settings.DetectUrlInMessage;
            toolBtnIgnore.Image = Program.Images.GetBitmap("ignore.gif");
            richOutput.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(richOutput_LinkClicked);
            txtInput.KeyUp += new System.Windows.Forms.KeyEventHandler(txtInput_KeyUp);
            Program.Settings.SettingsUpdated += new FmdcEventHandler(Settings_SettingsUpdated);
            UpdateNotificationText();
        }

        void Settings_SettingsUpdated(object sender, FmdcEventArgs e)
        {
            richOutput.DetectUrls = Program.Settings.DetectUrlInMessage;
        }

        void richOutput_LinkClicked(object sender, System.Windows.Forms.LinkClickedEventArgs e)
        {
            if (e.LinkText.StartsWith("adc://") ||
                e.LinkText.StartsWith("adcs://") ||
                e.LinkText.StartsWith("dchub://") ||
                e.LinkText.StartsWith("dchubs://"))
            {
                HubSetting setting = new HubSetting();
                setting.Address = e.LinkText;
                MainWindow.CurrentInstance.QuickConnect(setting);
            }
            else
            {
                try
                {
                    System.Diagnostics.Process.Start(e.LinkText);
                }
                catch
                {
                    // OS can't handle this url. Should we do anything with it?
                }
            }
        }

        void txtInput_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            if (!e.Control)
            {
                e.SuppressKeyPress = true;
                //e.Handled = true;
                if (e.KeyCode == System.Windows.Forms.Keys.Enter)
                    SendMessage();
            }
        }

        public OnlineStatus Info
        {
            get { return info; }
            set
            {
                info = value;
                Invoke(new MessageTab.update(UpdateStatus));
            }
        }

        public void AddMessage(Message msg)
        {
            string date = string.Empty;
            string name = string.Empty;
            string content = string.Empty;
            string str = string.Empty;
            if (Program.Settings.ShowDateStamp)
            {
                date = string.Format("[{0}] ", DateTime.Now.ToString(Program.Settings.DateStampFormat));
            }
            else
            {
                date = string.Empty;
            }
            if (msg.IsSystem)
            {
                name = "*** ";
                content = msg.Content;
            }
            else
            {
                name = string.Format("<{0}> ", msg.From);
                content = msg.Content;
            }
            str = string.Format("{0}{1}{2}\r\n", date, name, content);

            #region do formatings here
            lock (richOutput)
            {
                int selectedPos = (richOutput.SelectionStart == richOutput.TextLength ? -1 : richOutput.SelectionStart);
                int selectedLenght = richOutput.SelectionLength;
                int inputPos = richOutput.TextLength;
                richOutput.AppendText(str);
                // Color timestamp
                richOutput.Select(inputPos, date.Length);
                richOutput.SelectionColor = Color.Gray;
                // Color name
                richOutput.Select(inputPos + date.Length, name.Length);
                if (msg.IsSystem)
                    richOutput.SelectionColor = Color.Gray;
                else
                    richOutput.SelectionColor = Color.Blue;

                // Color Content
                if (msg.IsSystem)
                {
                    richOutput.Select(inputPos + date.Length + name.Length , content.Length);
                    richOutput.SelectionColor = Color.Gray;
                }

                // Add none standard URL:s as URL. For example dchub://
				int length = content.Length;
                if (Program.Settings.DetectUrlInMessage)
                {
                    int start = 0;
                    int tmpLength = 0;
                    while ((start = content.IndexOf("://", start)) != -1)
                    {
                        int tmpStart = inputPos + date.Length + name.Length + start;
                        tmpLength = 0;
                        richOutput.FindUrl(ref tmpStart, ref tmpLength);
                        if (tmpLength > 0)
                        {
                            richOutput.Select(tmpStart, tmpLength);
                            richOutput.SelectionColor = Color.Blue;
                            richOutput.SelectionFont = new Font(richOutput.SelectionFont.FontFamily, richOutput.SelectionFont.Size, FontStyle.Underline);
                        }
                        start += 3;
                    }
                }

                if (selectedPos == -1)
                    selectedPos = richOutput.TextLength;
                richOutput.SelectionStart = selectedPos;
                richOutput.SelectionLength = selectedLenght;
                richOutput.ScrollToCaret();
            }
            #endregion

            #region Notify
            Notification not = new Notification();
            not.Type = Notification.NotificationTypes.Message;
            if ((Notification.NotificationActions.None & notify) == Notification.NotificationActions.None)
                not.Action = (Notification.NotificationActions)Program.Settings.NotityMsgStatus;
            else
                not.Action = notify;
            not.Message = name + content;
            Program.Notification.AddNotification(not);
            #endregion
        }

        protected void UpdateStatus()
        {
            switch (info.Status)
            {
                case TcpConnection.Connected:
                    btnSend.Enabled = true;
                    txtInput.ReadOnly = false;
                    break;
                case TcpConnection.Connecting:
                case TcpConnection.Disconnected:
                    btnSend.Enabled = false;
                    txtInput.ReadOnly = true;
                    //ImageIndex = info.Status;
                    break;
                default:
                    //ImageIndex = TcpConnection.Connected;
                    break;
            }
        }

        protected void SendMessage()
        {
            Message msg = new Message();
            msg.Status = info;
            msg.Content = txtInput.Text.TrimEnd('\n').TrimEnd('\r');
            txtInput.Clear();
            txtInput.Focus();
            ActionUpdate(info, new FmdcEventArgs(0, msg));
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            SendMessage();
        }

        private void MessagePanel_Load(object sender, EventArgs e)
        {
        }

        void MessagePanel_ActionUpdate(object sender, FmdcEventArgs e) { }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            switch (notify)
            {
                case Notification.NotificationActions.None:
                    notify = Notification.NotificationActions.Sound;
                    break;
                case Notification.NotificationActions.Sound:
                    notify = Notification.NotificationActions.NotificationWindow;
                    break;
                case Notification.NotificationActions.NotificationWindow:
                    notify = Notification.NotificationActions.IconChange;
                    break;
                case Notification.NotificationActions.IconChange:
                    notify = Notification.NotificationActions.None;
                    break;
                default:
                    notify = Notification.NotificationActions.None;
                    break;
            }
            UpdateNotificationText();
        }

        protected void UpdateNotificationText()
        {
            if ((Notification.NotificationActions.None & notify) != Notification.NotificationActions.None)
            {
                toolStripButton1.Text = "Notify: " + notify.ToString();
            }
            else
            {
                bool isSet = false;
                Notification.NotificationActions tmpNotify = Notification.NotificationActions.None;
                //if (((int)Message.Notifications.None & Program.Settings.NotityMsgStatus) == (int)Message.Notifications.None)
                //    tmpNotify |= Message.Notifications.None;
                if (((int)Notification.NotificationActions.IconChange & Program.Settings.NotityMsgStatus) == (int)Notification.NotificationActions.IconChange)
                {
                    tmpNotify |= Notification.NotificationActions.IconChange;
                    isSet = true;
                }
                if (((int)Notification.NotificationActions.NotificationWindow & Program.Settings.NotityMsgStatus) == (int)Notification.NotificationActions.NotificationWindow)
                {
                    tmpNotify |= Notification.NotificationActions.NotificationWindow;
                    isSet = true;
                }
                if (((int)Notification.NotificationActions.Sound & Program.Settings.NotityMsgStatus) == (int)Notification.NotificationActions.Sound)
                {
                    tmpNotify |= Notification.NotificationActions.Sound;
                    isSet = true;
                }

                if (isSet)
                    tmpNotify = tmpNotify & ~Notification.NotificationActions.None;
                toolStripButton1.Text = "Notify: " + tmpNotify;
            }
        }

        private void outCopyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richOutput.Copy();
        }
    }
}
